home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / BlitPixie / Sources / BlitPixieRLE.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  24.1 KB  |  1,322 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixieRLE
  3. //        a fast Run-Length-Encoding masked software blitter.
  4. //
  5. //        based on original code by Mick Foley <mick@emf.net>
  6. //        from the book "Tricks of the Mac Game Programming Gurus" by Hayden Books.
  7. //
  8. //        Written by Anders F Björklund <afb@algonet.se>, Nov. 1999
  9. //        © 1998-99 afb. All rights reserved. 
  10. ///--------------------------------------------------------------------------------------
  11.  
  12. #ifndef __BLITPIXIE__
  13. #include "BlitPixieHeader.h"
  14. #endif
  15.  
  16. #include "BlitPixieAsm.h"
  17.  
  18. #define ALIGN_PTR(p)                ( -((long) p) & 3)
  19.  
  20. #pragma mark *** PowerPC asm:
  21. #if USE_PPC_ASSEMBLY
  22.  
  23. ///--------------------------------------------------------------------------------------
  24. //        BlitPixieRLE - no clipping performed
  25. ///--------------------------------------------------------------------------------------
  26.  
  27. ASM_FUNC void BlitPixieRLE(
  28.     register unsigned char *srcTokens,                // r3
  29.     register unsigned char *dstPixelPTemp,            // r4
  30.     register unsigned long dstRowBytes)                // r5
  31. {
  32. #define r_token                    r31
  33. #define r_op                    r30
  34. #define r_count                    r31    // recycled
  35. #define r_blocks                r29
  36. #define r_dstRow                r28
  37. #define r_dstBytes                r27
  38. #define r_align                    r26
  39.  
  40.     ASM_BEGIN
  41.     stmw    r26,-24(SP)
  42.     
  43.     mr        r_dstRow,r4
  44.     mr        r_dstBytes,r5
  45.     
  46. @tokenloop:
  47.     lwz        r_token,0(r3)
  48.     addi    r3,r3,4
  49.     rlwinm    r_op,r_token,32-kTokenShift,kTokenShift,31
  50.     rlwinm    r_count,r_token,0,32-kTokenShift,31
  51.     
  52.     cmplwi    r_op,kDrawPixelsToken
  53. //    STALL!
  54.     bne        @notdraw        
  55. //================================================== Draw Token
  56.  
  57.     rlwinm    r0,r4,0,30,31
  58.     rlwinm  r_blocks,r_count,27,5,31    // blocks = bytes / 32
  59.     rlwinm  r_count,r_count,0,27,31        // bytes %= 32
  60.     
  61.     cmplwi    cr5,r0,0
  62.     cmplwi    cr6,r_blocks,0
  63.     cmplwi    cr7,r_count,0
  64.     
  65.     mtctr    r_blocks
  66.     mtxer    r_count
  67.         
  68.     beq        cr6,@skipblocks
  69.     bne        cr5,@unaligned
  70.  
  71. @aligned:
  72. @doubleloop:
  73.         lfd      fp1,0(r3)
  74.         lfd      fp2,8(r3)
  75.         lfd      fp3,16(r3)
  76.         lfd      fp4,24(r3)
  77.         addi     r3,r3,32
  78.         stfd     fp1,0(r4)
  79.         stfd     fp2,8(r4)
  80.         stfd     fp3,16(r4)
  81.         stfd     fp4,24(r4)
  82.         addi     r4,r4,32
  83.         bdnz     @doubleloop
  84.     b         @skipblocks
  85.  
  86. @unaligned:
  87. @blockloop:
  88.         lwz      r5,0(r3)
  89.         lwz      r6,4(r3)
  90.         lwz      r7,8(r3)
  91.         lwz      r8,12(r3)
  92.         lwz      r9,16(r3)
  93.         lwz      r10,20(r3)
  94.         lwz      r11,24(r3)
  95.         lwz      r12,28(r3)
  96.         addi     r3,r3,32
  97.         stw      r5,0(r4)
  98.         stw      r6,4(r4)
  99.         stw      r7,8(r4)
  100.         stw      r8,12(r4)
  101.         stw      r9,16(r4)
  102.         stw      r10,20(r4)
  103.         stw      r11,24(r4)
  104.         stw      r12,28(r4)
  105.         addi     r4,r4,32
  106.         bdnz     @blockloop
  107. @skipblocks:
  108.  
  109.     beq         cr7,@skipbytes
  110.         lswx     r5,r0,r3
  111.         add         r3,r3,r_count
  112.         stswx     r5,r0,r4
  113.         add         r4,r4,r_count
  114. @skipbytes:
  115.  
  116.     addi        r3,r3,3
  117.     rlwinm        r3,r3,0,0,29
  118.  
  119.     b        @tokenloop
  120.  
  121. @notdraw:
  122.     cmplwi    r_op,kSkipPixelsToken
  123. //    STALL!
  124.     bne        @notskip        
  125. //================================================== Skip Token
  126.     add        r4,r4,r_count
  127.     b        @tokenloop
  128.  
  129. @notskip:
  130.     cmplwi    r_op,kSingleColorToken
  131. //    STALL!
  132.     bne        @notfill    
  133. //================================================== Fill Token
  134.  
  135.     lwz        r5,0(r3)
  136.     addi    r3,r3,4
  137.     
  138.     rlwinm    r0,r4,0,30,31
  139.     rlwinm  r_blocks,r_count,27,5,31    // blocks = bytes / 32
  140.     rlwinm  r_count,r_count,0,27,31        // bytes %= 32
  141.  
  142.     cmplwi    cr5,r0,0
  143.     cmplwi    cr6,r_blocks,0
  144.     cmplwi    cr7,r_count,0
  145.     
  146.     mtctr     r_blocks
  147.     mtxer     r_count
  148.         
  149.         beq         cr6,@skipblocks2
  150.         bne         cr5,@unaligned2
  151. @aligned2:
  152.  
  153.         stw         r5,-32(SP)
  154.         stw         r5,-28(SP)
  155.         lfd         fp0,-32(SP)
  156.  
  157. @doubleloop2:
  158.         stfd     fp0,0(r4)
  159.         stfd     fp0,8(r4)
  160.         stfd     fp0,16(r4)
  161.         stfd     fp0,24(r4)
  162.         addi     r4,r4,32
  163.         bdnz     @doubleloop2
  164.     b         @skipblocks2
  165.  
  166. @unaligned2:
  167. @blockloop2:
  168.         stw      r5,0(r4)
  169.         stw      r5,4(r4)
  170.         stw      r5,8(r4)
  171.         stw      r5,12(r4)
  172.         stw      r5,16(r4)
  173.         stw      r5,20(r4)
  174.         stw      r5,24(r4)
  175.         stw      r5,28(r4)
  176.         addi     r4,r4,32
  177.         bdnz     @blockloop2
  178. @skipblocks2:
  179.  
  180.         beq         cr7,@skipbytes2
  181.         mr         r6,r5
  182.         mr         r7,r5
  183.         mr         r8,r5
  184.         mr         r9,r5
  185.         mr         r10,r5
  186.         mr         r11,r5
  187.         mr         r12,r5
  188.         stswx     r5,r0,r4
  189.         add         r4,r4,r_count
  190. @skipbytes2:
  191.  
  192.     b        @tokenloop
  193.  
  194. @notfill:
  195.     cmplwi    r_op,kLineStartToken
  196. //    STALL!
  197.     bne        @notstart        
  198. //================================================== Line Start Token
  199.     mr        r4,r_dstRow
  200.     add        r_dstRow,r_dstRow,r_dstBytes
  201.     b        @tokenloop
  202.  
  203. @notstart:
  204.     cmplwi    r_op,kEndShapeToken
  205.     beq        @end
  206.  
  207. @notend:
  208. //    bl    Debugger        // <-- unknown token encountered
  209. //    nop
  210.  
  211. //================================================== End Shape Token
  212. @end:
  213.     lmw        r26,-24(SP)
  214.     ASM_END
  215. }
  216.  
  217. ///--------------------------------------------------------------------------------------
  218. //        BlitPixieRLEClipped
  219. ///--------------------------------------------------------------------------------------
  220.  
  221. ASM_FUNC void BlitPixieRLEClipped(
  222.     register unsigned char *srcTokens,                // r3
  223.     register unsigned char *dstPixelPTemp,            // r4
  224.     register unsigned long dstRowBytes,                // r5
  225.     register Rect *dstClipRect)                        // r6
  226. {
  227. #define r_token                    r31
  228. #define r_op                    r30
  229. #define r_count                    r31        // recycled
  230. #define r_blocks                r29
  231. #define r_dstRow                r28
  232. #define r_dstBytes                r27
  233. #define r_spanend                r26
  234. #define r_extra                    r25
  235. #define r_inc                    r24
  236. #define r_clipLeft                r23
  237. #define r_clipRight                r22
  238. #define r_clipTop                r21
  239. #define r_clipBottom            r20
  240. #define r_x                        r19
  241. #define r_y                        r18
  242.  
  243.     ASM_BEGIN
  244.     stmw    r18,-60(SP)
  245.  
  246.     lha        r_clipTop,0(r6)
  247.     lha        r_clipLeft,2(r6)
  248.     lha        r_clipBottom,4(r6)
  249.     lha        r_clipRight,6(r6)
  250.  
  251.     mr        r_dstRow,r4
  252.     mr        r_dstBytes,r5
  253.     li        r_y,0
  254.  
  255. @tokenloop:
  256.     lwz        r_token,0(r3)
  257.     addi    r3,r3,4
  258.     rlwinm    r_op,r_token,32-kTokenShift,kTokenShift,31
  259.     rlwinm    r_count,r_token,0,32-kTokenShift,31
  260.  
  261.     cmplwi    r_op,kDrawPixelsToken
  262.     bne        @notdraw        
  263. //================================================== Draw Token
  264.  
  265. //    CHECK LEFT BORDER
  266.     add        r_spanend,r_x,r_count
  267.     subi    r_spanend,r_spanend,1
  268.  
  269.     cmplw    cr5,r_x,r_clipLeft
  270.     cmplw    cr6,r_spanend,r_clipLeft
  271.     bge        cr5,@noleftclip
  272.     ble        cr6,@skiprun
  273.     
  274. @leftclip:                            // clip left
  275.     sub        r_extra,r_clipLeft,r_x    
  276.     add        r3,r3,r_extra
  277.     add        r4,r4,r_extra
  278.     add        r_x,r_x,r_extra
  279.     sub        r_count,r_count,r_extra
  280. @noleftclip:
  281.  
  282. //    CHECK RIGHT BORDER
  283.     li        r_extra,0
  284.  
  285.     cmplw    cr5,r_spanend,r_clipRight
  286.     cmplw    cr6,r_x,r_clipRight
  287.     blt        cr5,@norightclip
  288.     bge        cr6,@skiprun
  289.  
  290. @rightclip:                            // clip right
  291.     sub        r_extra,r_spanend,r_clipRight
  292.     sub        r_count,r_count,r_extra
  293. @norightclip:
  294.  
  295. //    DRAW SPAN
  296.     rlwinm   r_blocks,r_count,27,5,31    // blocks = bytes >> 5
  297.     rlwinm   r_count,r_count,0,27,31    // bytes &= 31
  298.  
  299.     cmplwi     cr6,r_blocks,0
  300.     cmplwi     cr7,r_count,0
  301.     
  302.     mtxer     r_count
  303.     add         r_count,r_count,r_extra        // adjust for right clipping
  304.         
  305.         beq         cr6,@skipblocks
  306.         mtctr     r_blocks
  307. @blockloop:
  308.         addi     r_x,r_x,32
  309.         lwz      r5, 0(r3)
  310.         lwz      r6, 4(r3)
  311.         lwz      r7, 8(r3)
  312.         lwz      r8,12(r3)
  313.         lwz      r9,16(r3)
  314.         lwz      r10,20(r3)
  315.         lwz      r11,24(r3)
  316.         lwz      r12,28(r3)
  317.         addi     r3,r3,32
  318.         stw      r5, 0(r4)
  319.         stw      r6, 4(r4)
  320.         stw      r7, 8(r4)
  321.         stw      r8,12(r4)
  322.         stw      r9,16(r4)
  323.         stw      r10,20(r4)
  324.         stw      r11,24(r4)
  325.         stw      r12,28(r4)
  326.         addi     r4,r4,32
  327.         bdnz     @blockloop
  328. @skipblocks:
  329.  
  330.         beq         cr7,@skiprun
  331.         lswx     r5,r0,r3
  332.         stswx     r5,r0,r4
  333. @skiprun:
  334.  
  335.     add        r3,r3,r_count
  336.     add        r4,r4,r_count
  337.     add        r_x,r_x,r_count
  338.  
  339.     addi        r3,r3,3
  340.     rlwinm        r3,r3,0,0,29
  341.  
  342.     b        @tokenloop
  343.  
  344. @notdraw:
  345.     cmplwi    r_op,kSkipPixelsToken
  346.     bne        @notskip    
  347. //================================================== Skip Token
  348.     add        r4,r4,r_count
  349.     add        r_x,r_x,r_count
  350.     b        @tokenloop
  351.  
  352. @notskip:
  353.     cmplwi    r_op,kSingleColorToken
  354.     bne        @notfill    
  355. //================================================== Fill Token
  356.  
  357. //    CHECK LEFT BORDER
  358.     add        r_spanend,r_x,r_count
  359.     subi    r_spanend,r_spanend,1
  360.     
  361.     cmplw    cr5,r_x,r_clipLeft
  362.     cmplw    cr6,r_spanend,r_clipLeft
  363.     bge        cr5,@noleftclip2
  364.     ble        cr6,@skiprun2
  365.     
  366. @leftclip2:                            // clip left
  367.     sub        r_extra,r_clipLeft,r_x    
  368.     add        r4,r4,r_extra
  369.     add        r_x,r_x,r_extra
  370.     sub        r_count,r_count,r_extra
  371. @noleftclip2:
  372.  
  373. //    CHECK RIGHT BORDER
  374.     li        r_extra,0
  375.  
  376.     cmplw    cr5,r_spanend,r_clipRight
  377.     cmplw    cr6,r_x,r_clipRight
  378.     blt        cr5,@norightclip2
  379.     bge        cr6,@skiprun2
  380.  
  381. @rightclip2:                            // clip right
  382.     sub        r_extra,r_spanend,r_clipRight
  383.     sub        r_count,r_count,r_extra
  384. @norightclip2:
  385.  
  386. //    DRAW SPAN
  387.     rlwinm   r_blocks,r_count,27,5,31    // blocks = bytes >> 5
  388.     rlwinm   r_count,r_count,0,27,31    // bytes &= 31
  389.  
  390.     lwz      r5,0(r3)
  391.     
  392.     cmplwi     cr6,r_blocks,0
  393.     cmplwi     cr7,r_count,0
  394.     
  395.     mtxer     r_count
  396.     add         r_count,r_count,r_extra        // adjust for right clipping
  397.     
  398.         beq         cr6,@skipblocks2
  399.         mtctr     r_blocks
  400. @blockloop2:
  401.         addi     r_x,r_x,32
  402.         stw      r5,0(r4)
  403.         stw      r5,4(r4)
  404.         stw      r5,8(r4)
  405.         stw      r5,12(r4)
  406.         stw      r5,16(r4)
  407.         stw      r5,20(r4)
  408.         stw      r5,24(r4)
  409.         stw      r5,28(r4)
  410.         addi     r4,r4,32
  411.         bdnz     @blockloop2
  412. @skipblocks2:
  413.  
  414.         beq         cr7,@skiprun2
  415.         mr         r6,r5    
  416.         mr         r7,r5    
  417.         mr         r8,r5    
  418.         mr         r9,r5    
  419.         mr         r10,r5    
  420.         mr         r11,r5    
  421.         mr         r12,r5    
  422.         stswx     r5,r0,r4
  423. @skiprun2:
  424.  
  425.     addi    r3,r3,4
  426.     add        r4,r4,r_count
  427.     add        r_x,r_x,r_count
  428.  
  429.     b        @tokenloop
  430.  
  431. @notfill:
  432.     cmplwi    r_op,kLineStartToken
  433.     bne        @notstart        
  434. //================================================== Line Start Token
  435.     cmplw    r_y,r_clipTop
  436.     bge        @notabove    
  437.     add        r3,r3,r_count        // skip if above clip
  438. @notabove:
  439.  
  440.     cmplw    r_y,r_clipBottom
  441.     bge        @end            // end if below clip
  442.  
  443.     mr        r4,r_dstRow
  444.     add        r_dstRow,r_dstRow,r_dstBytes
  445.     li        r_x,0
  446.     addi    r_y,r_y,1
  447.  
  448.     b        @tokenloop
  449.  
  450. @notstart:
  451.     cmplwi    r_op,kEndShapeToken
  452.     beq        @end
  453.  
  454. @notend:
  455. //    bl    Debugger        // <-- unknown token encountered
  456. //    nop
  457.  
  458. @end:
  459. //================================================== End Shape Token
  460.  
  461.     lmw        r18,-60(SP)
  462.     ASM_END
  463. }
  464.  
  465. #pragma mark *** 680X0 asm:
  466. #elif USE_68K_ASSEMBLY
  467.  
  468. ///--------------------------------------------------------------------------------------
  469. //        BlitPixieRLE - no clipping performed
  470. ///--------------------------------------------------------------------------------------
  471.  
  472. ASM_FUNC void BlitPixieRLE(
  473.     unsigned char *srcTokens,    
  474.     unsigned char *dstPixel,
  475.     unsigned long dstRowBytes)
  476. {
  477.     ASM_BEGIN
  478.  
  479.     MOVE.L        A2,-(SP)
  480.     
  481.     MOVEA.L        srcTokens,A0
  482.     MOVEA.L        dstPixel,A1
  483.     MOVEA.L        A1,A2
  484.     MOVE.L        dstRowBytes,D2
  485.  
  486.     CLR.L        D1
  487.     
  488. @tokenloop:
  489.     MOVE.L        (A0)+,D0
  490.     MOVE.L        D0,D1
  491.  
  492.     ROL.L        #32 - kTokenShift,D0
  493.     ANDI.L        #kCountMask,D1
  494.  
  495.     CMPI.B        #kDrawPixelsToken,D0    
  496.     BNE            @notdraw
  497.     
  498. //================================================== Draw Pixels
  499.  
  500.     MOVE.W        D1,D0
  501.     LSR.W        #4,D0
  502.     BEQ.S        @noloops
  503.  
  504.     SUBQ.W        #1,D0    
  505. @loop:
  506.     MOVE.L        (A0)+,(A1)+
  507.     MOVE.L        (A0)+,(A1)+
  508.     MOVE.L        (A0)+,(A1)+
  509.     MOVE.L        (A0)+,(A1)+
  510.     
  511.     DBRA        D0,@loop
  512. @noloops:
  513.     
  514.     MOVE.W        D1,D0
  515.     ANDI.W        #8,D0
  516.     BEQ.S        @not8
  517.     MOVE.L        (A0)+,(A1)+
  518.     MOVE.L        (A0)+,(A1)+
  519. @not8:
  520.  
  521.     MOVE.W        D1,D0
  522.     ANDI.W        #4,D0
  523.     BEQ.S        @not4
  524.     MOVE.L        (A0)+,(A1)+
  525. @not4:
  526.  
  527.     MOVE.W        D1,D0
  528.     ANDI.W        #2,D0
  529.     BEQ.S        @not2
  530.     MOVE.W        (A0)+,(A1)+
  531. @not2:
  532.  
  533.     MOVE.W        D1,D0
  534.     ANDI.W        #1,D0
  535.     BEQ.S        @not1
  536.     MOVE.B        (A0)+,(A1)+
  537. @not1:
  538.     
  539.     MOVE.L        A0,D0
  540.     ADDQ.L        #3,D0
  541.     ANDI.W        #~3,D0
  542.     MOVEA.L     D0,A0
  543.     
  544.     BRA            @tokenloop
  545.  
  546. @notdraw:    
  547.     CMPI.B        #kSkipPixelsToken,D0
  548.     BNE            @notskip
  549. //================================================== Skip Pixels
  550.     
  551.     ADDA.L        D1,A1
  552.     
  553.     BRA            @tokenloop
  554.  
  555. @notskip:    
  556.     CMPI.B        #kSingleColorToken,D0
  557.     BNE            @notfill
  558. //================================================== Fill Pixels
  559.  
  560.     MOVE.W        D1,D0
  561.     LSR.W        #4,D0
  562.     BEQ            @nofillloops
  563.  
  564.     SUBQ.W        #1,D0    
  565. @fillloop:
  566.     MOVE.L        (A0),(A1)+
  567.     MOVE.L        (A0),(A1)+
  568.     MOVE.L        (A0),(A1)+
  569.     MOVE.L        (A0),(A1)+
  570.     
  571.     DBRA        D0,@fillloop
  572. @nofillloops:
  573.     
  574.     MOVE.W        D1,D0
  575.     ANDI.W        #8,D0
  576.     BEQ.S        @notfill8
  577.     MOVE.L        (A0),(A1)+
  578.     MOVE.L        (A0),(A1)+
  579. @notfill8:
  580.  
  581.     MOVE.W        D1,D0
  582.     ANDI.W        #4,D0
  583.     BEQ.S        @notfill4
  584.     MOVE.L        (A0),(A1)+
  585. @notfill4:
  586.  
  587.     MOVE.W        D1,D0
  588.     ANDI.W        #2,D0
  589.     BEQ.S        @notfill2
  590.     MOVE.W        (A0),(A1)+
  591. @notfill2:
  592.  
  593.     MOVE.W        D1,D0
  594.     ANDI.W        #1,D0
  595.     BEQ.S        @notfill1
  596.     MOVE.B        (A0),(A1)+
  597. @notfill1:
  598.     
  599.     ADDQ.L        #4,A0
  600.     
  601.     BRA            @tokenloop
  602.  
  603. @notfill:    
  604.     CMPI.B        #kLineStartToken,D0
  605.     BNE            @notline
  606. //================================================== Line Start
  607.  
  608.     MOVEA.L        A2,A1
  609.     ADDA.L        D2,A2
  610.  
  611.     BRA            @tokenloop
  612.  
  613. @notline:
  614.     CMPI.B        #kEndShapeToken,D0
  615.     BEQ            @end
  616. //================================================== Shape Ends
  617.     
  618. @notend:
  619. //    _Debugger        // <-- unknown token encountered
  620.  
  621. @end:
  622.     MOVE.L        (SP)+,A2
  623.  
  624.     ASM_END
  625. }
  626.  
  627. ///--------------------------------------------------------------------------------------
  628. //        BlitPixieRLEClipped
  629. ///--------------------------------------------------------------------------------------
  630.  
  631. ASM_FUNC void BlitPixieRLEClipped(
  632.     unsigned char *srcTokens,    
  633.     unsigned char *dstPixel,
  634.     unsigned long dstRowBytes,
  635.     Rect *dstClipRect)
  636. {
  637. #define D_x                D3
  638. #define D_y                D4
  639. #define D_blocks        D5
  640. #define D_extra            D6
  641.  
  642. #define D_clipTop         (A3)
  643. #define D_clipLeft        2(A3)
  644. #define D_clipBottom    4(A3)
  645. #define D_clipRight        6(A3)
  646.     
  647.     ASM_BEGIN
  648.  
  649.     MOVEM.L          D3-D6/A2-A3,-(SP)        // D0-D2,A0-A1 are volatile
  650.  
  651.     MOVEA.L        srcTokens,A0
  652.     MOVEA.L        dstPixel,A1
  653.     MOVEA.L        A1,A2
  654.     MOVE.L        dstRowBytes,D2
  655.     MOVEA.L        dstClipRect,A3
  656.  
  657.     MOVEQ        #0,D_y
  658.     CLR.L        D1
  659.     CLR.L        D_extra
  660.     
  661. @tokenloop:
  662.     MOVE.L        (A0)+,D0
  663.     MOVE.L        D0,D1
  664.     ROL.L        #32 - kTokenShift,D0
  665.     ANDI.L        #kCountMask,D1
  666.  
  667.     CMPI.B        #kDrawPixelsToken,D0
  668.     BNE            @notdraw
  669. //================================================== Draw Token
  670.  
  671.     MOVE.W        D_x,D0
  672.     ADD.W        D1,D0
  673.     SUBQ.W        #1,D0
  674.  
  675.     CMP.W        D_clipLeft,D_x
  676.     BGE.S        @noleftclip
  677.     CMP.W        D_clipLeft,D0
  678.     BGT.S        @leftclip
  679.  
  680. @skipleft:
  681.         // skip this run (totally outside)
  682.     ADDA.L        D1,A0
  683.     ADDA.L        D1,A1
  684.     ADD.W        D1,D_x
  685.  
  686.     BRA            @skip
  687.  
  688. @leftclip:
  689.         // clip left (clipLeft - x)
  690.     MOVE.W        D_clipLeft,D_extra
  691.     SUB.W        D_x,D_extra
  692.     SUB.W        D_extra,D1
  693.  
  694.     ADDA.L        D_extra,A0
  695.     ADDA.L        D_extra,A1
  696.     ADD.W        D_extra,D_x
  697.     
  698. @noleftclip:
  699.     MOVEQ        #0,D_extra
  700.  
  701.     CMP.W        D_clipRight,D0
  702.     BLT.S        @norightclip
  703.     
  704.     CMP.W        D_clipRight,D_x
  705.     BLT.S        @rightclip
  706.  
  707. @skipright:
  708.     BRA            @skipleft
  709.  
  710. @rightclip:
  711.     
  712.         // clip right
  713.     MOVE.W        D0,D_extra
  714.     SUB.W        D_clipRight,D_extra
  715.  
  716.     SUB.W        D_extra,D1
  717.     
  718. @norightclip:
  719.     MOVE.W        D1,D0
  720.     LSR.W        #4,D0
  721.     BEQ.S        @noloops
  722.  
  723.     SUBQ.W        #1,D0    
  724. @loop:
  725.     MOVE.L        (A0)+,(A1)+
  726.     MOVE.L        (A0)+,(A1)+
  727.     MOVE.L        (A0)+,(A1)+
  728.     MOVE.L        (A0)+,(A1)+
  729.     
  730.     DBRA        D0,@loop
  731. @noloops:
  732.     
  733.     MOVE.W        D1,D0
  734.     ANDI.W        #8,D0
  735.     BEQ.S        @not8
  736.     MOVE.L        (A0)+,(A1)+
  737.     MOVE.L        (A0)+,(A1)+
  738. @not8:
  739.  
  740.     MOVE.W        D1,D0
  741.     ANDI.W        #4,D0
  742.     BEQ.S        @not4
  743.     MOVE.L        (A0)+,(A1)+
  744. @not4:
  745.  
  746.     MOVE.W        D1,D0
  747.     ANDI.W        #2,D0
  748.     BEQ.S        @not2
  749.     MOVE.W        (A0)+,(A1)+
  750. @not2:
  751.  
  752.     MOVE.W        D1,D0
  753.     ANDI.W        #1,D0
  754.     BEQ.S        @not1
  755.     MOVE.B        (A0)+,(A1)+
  756. @not1:
  757.  
  758.     ADD.W        D1,D_x
  759.  
  760.         // adjust for right clipping
  761.     ADDA.L        D_extra,A0
  762.     ADDA.L        D_extra,A1
  763.     ADD.W        D_extra,D_x
  764.  
  765. @skip:
  766.     MOVE.L        A0,D0
  767.     ADDQ.L        #3,D0
  768.     ANDI.W        #~3,D0
  769.     MOVEA.L     D0,A0
  770.     
  771.     BRA            @tokenloop
  772.  
  773. @notdraw:
  774.     CMPI.B        #kSkipPixelsToken,D0
  775.     BNE.S        @notskip        
  776. //================================================== Skip Pixels
  777.  
  778.     ADDA.L        D1,A1
  779.     ADD.W        D1,D_x
  780.  
  781.     BRA            @tokenloop
  782.  
  783. @notskip:
  784.     CMPI.B        #kSingleColorToken,D0
  785.     BNE            @notfill        
  786. //================================================== Fill Pixels
  787.  
  788.     MOVE.W        D_x,D0
  789.     ADD.W        D1,D0
  790.     SUBQ.W        #1,D0
  791.  
  792.     CMP.W        D_clipLeft,D_x
  793.     BGE.S        @noleftclipFill
  794.     CMP.W        D_clipLeft,D0
  795.     BGT.S        @leftclipFill
  796.  
  797. @skipleftFill:
  798.         // skip this run (totally outside)
  799.     ADDA.L        D1,A1
  800.     ADD.W        D1,D_x
  801.  
  802.     ADDQ.L        #4,A0
  803.     
  804.     BRA            @tokenloop
  805.  
  806. @leftclipFill:
  807.         // clip left (clipLeft - x)
  808.     MOVE.W        D_clipLeft,D_extra
  809.     SUB.W        D_x,D_extra
  810.     SUB.W        D_extra,D1
  811.  
  812.     ADDA.L        D_extra,A1
  813.     ADD.W        D_extra,D_x
  814.     
  815. @noleftclipFill:
  816.     MOVEQ        #0,D_extra
  817.  
  818.     CMP.W        D_clipRight,D0
  819.     BLT.S        @norightclipFill
  820.     
  821.     CMP.W        D_clipRight,D_x
  822.     BLT.S        @rightclipFill
  823.  
  824. @skiprightFill:
  825.     BRA            @skipleftFill
  826.  
  827. @rightclipFill:
  828.     
  829.         // clip right
  830.     MOVE.W        D0,D_extra
  831.     SUB.W        D_clipRight,D_extra
  832.  
  833.     SUB.W        D_extra,D1
  834.     
  835. @norightclipFill:
  836.  
  837.     MOVE.W        D1,D0
  838.     LSR.W        #4,D0
  839.     BEQ.S        @noloopsFill
  840.  
  841.     SUBQ.W        #1,D0    
  842. @loopFill:
  843.     MOVE.L        (A0),(A1)+
  844.     MOVE.L        (A0),(A1)+
  845.     MOVE.L        (A0),(A1)+
  846.     MOVE.L        (A0),(A1)+
  847.     
  848.     DBRA        D0,@loopFill
  849. @noloopsFill:
  850.     
  851.     MOVE.W        D1,D0
  852.     ANDI.W        #8,D0
  853.     BEQ.S        @notFill8
  854.     MOVE.L        (A0),(A1)+
  855.     MOVE.L        (A0),(A1)+
  856. @notFill8:
  857.  
  858.     MOVE.W        D1,D0
  859.     ANDI.W        #4,D0
  860.     BEQ.S        @notFill4
  861.     MOVE.L        (A0),(A1)+
  862. @notFill4:
  863.  
  864.     MOVE.W        D1,D0
  865.     ANDI.W        #2,D0
  866.     BEQ.S        @notFill2
  867.     MOVE.W        (A0),(A1)+
  868. @notFill2:
  869.  
  870.     MOVE.W        D1,D0
  871.     ANDI.W        #1,D0
  872.     BEQ.S        @notFill1
  873.     MOVE.B        (A0),(A1)+
  874. @notFill1:
  875.  
  876.     ADD.W        D1,D_x
  877.  
  878.         // adjust for right clipping
  879.     ADDA.L        D_extra,A1
  880.     ADD.W        D_extra,D_x
  881.  
  882.     ADDQ.L        #4,A0
  883.     
  884.     BRA            @tokenloop
  885.  
  886. @notfill:
  887.     CMPI.B        #kLineStartToken,D0
  888.     BNE.S        @notstart        
  889. //================================================== Line Start
  890.     
  891.     CMP.W    D_clipTop,D_y
  892.     BGE.S    @notabove    
  893.     ADDA.L    D1,A0            // skip line if above clip
  894. @notabove:
  895.     CMP.W    D_clipBottom,D_y
  896.     BGE        @end            // end if below clip
  897.     
  898.     MOVEQ    #0,D_x
  899.     ADDQ.W    #1,D_y
  900.     
  901.     MOVEA.L    A2,A1
  902.     ADDA.L    D2,A2
  903.  
  904.     BRA        @tokenloop
  905.  
  906. @notstart:
  907.     CMPI.B        #kEndShapeToken,D0
  908.     BEQ            @end
  909.  
  910. @notend:
  911. //    _Debugger        // <-- unknown token encountered
  912.  
  913. @end:
  914. //================================================== End Shape Token
  915.  
  916.     MOVEM.L      (SP)+,D3-D6/A2-A3
  917.     ASM_END
  918. }
  919.  
  920. #pragma mark *** Generic C:
  921. #elif USE_GENERIC_C
  922.  
  923. ///--------------------------------------------------------------------------------------
  924. //        BlitPixieRLE - no clipping performed
  925. ///--------------------------------------------------------------------------------------
  926.  
  927. void BlitPixieRLE(
  928.     unsigned char *srcTokens,    
  929.     unsigned char *dstPixel,
  930.     unsigned long dstRowBytes)
  931. {
  932.     unsigned long    token,op,count;
  933.     unsigned char     *dstRow;
  934.     
  935.     dstRow = dstPixel;
  936.     
  937.     do
  938.     {
  939.         token = *((TokenDataType *) srcTokens);
  940.         srcTokens += sizeof(TokenDataType);
  941.         
  942.         op = token >> kTokenShift;
  943.         count = token & kCountMask;
  944.     
  945.         switch ( op )
  946.         {
  947.             case kDrawPixelsToken:
  948.                 BlitPixieMemCopy( dstPixel, srcTokens, count );
  949.                 srcTokens += count;
  950.                 srcTokens += ALIGN_PTR(srcTokens);
  951.                 dstPixel += count;
  952.                 break;
  953.             case kSkipPixelsToken:
  954.                 dstPixel += count;
  955.                 break;
  956.             case kSingleColorToken:
  957.                 BlitPixieMemSet( dstPixel, *((unsigned long *) srcTokens), count );
  958.                 srcTokens += sizeof(long);
  959.                 dstPixel += count;
  960.                 break;
  961.             case kLineStartToken:
  962.                 dstPixel = dstRow;
  963.                 dstRow += dstRowBytes;
  964.                 break;
  965.             case kEndShapeToken:
  966.                 break;
  967.             default:
  968.                 BLITPIXIE_DEBUGGER("BlitPixieRLE : compiled data contains unknown token!");
  969.                 return;
  970.         }
  971.     
  972.     } while ( op != kEndShapeToken );
  973.     
  974. }
  975.  
  976. ///--------------------------------------------------------------------------------------
  977. //        BlitPixieRLEClipped
  978. ///--------------------------------------------------------------------------------------
  979.  
  980. void BlitPixieRLEClipped(
  981.     unsigned char *srcTokens,
  982.     unsigned char *dstPixel,
  983.     unsigned long dstOffset,
  984.     Rect *dstClipRect )
  985. {
  986.     unsigned short        token,op;
  987.     long                count,extra,spanend;
  988.     unsigned char        *dstRow;
  989.     int                    x,y;
  990.  
  991.     y = 0;
  992.     dstRow = dstPixel;
  993.     
  994.     do
  995.     {
  996.         token = *srcTokens++;
  997.  
  998.         op = token >> kTokenShift;
  999.         count = token & kCountMask;
  1000.     
  1001.         switch ( op )
  1002.         {
  1003.             case kDrawPixelsToken:
  1004.                 
  1005.                 spanend = x + count - 1;
  1006.                 
  1007.                 if ( x < dstClipRect->right && spanend > dstClipRect->left )
  1008.                 {
  1009.                         // clip left
  1010.                     if ( x < dstClipRect->left )
  1011.                     {
  1012.                         extra = dstClipRect->left - x;
  1013.                     
  1014.                         count -= extra;
  1015.                     
  1016.                         x += extra;
  1017.                         dstPixel += extra;
  1018.                         srcTokens += extra;
  1019.                     }
  1020.                     
  1021.                         // clip right
  1022.                     extra = 0;
  1023.                     if ( spanend > dstClipRect->right )
  1024.                     {
  1025.                         extra = spanend - dstClipRect->right;
  1026.                     
  1027.                         count -= extra;
  1028.                     }
  1029.                     
  1030.                     BlitPixieMemCopy( dstPixel, srcTokens, count );
  1031.                     
  1032.                     x += extra;
  1033.                     dstPixel += extra;
  1034.                     srcTokens += extra;
  1035.                     
  1036.                 }
  1037.                 
  1038.                 x += count;
  1039.                 dstPixel += count;
  1040.                 srcTokens += count;
  1041.                 srcTokens += ALIGN_PTR(srcTokens);
  1042.                 
  1043.                 break;
  1044.             
  1045.             case kSkipPixelsToken:
  1046.                 x += count;
  1047.                 dstPixel += count;
  1048.                 break;
  1049.             
  1050.             case kSingleColorToken:
  1051.                 
  1052.                 spanend = x + count -1;
  1053.                 
  1054.                 if ( x < dstClipRect->right && spanend > dstClipRect->left )
  1055.                 {
  1056.                         // clip left
  1057.                     if ( x < dstClipRect->left )
  1058.                     {
  1059.                         extra = dstClipRect->left - x;
  1060.                     
  1061.                         count -= extra;
  1062.                     
  1063.                         x += extra;
  1064.                         dstPixel += extra;
  1065.                     }
  1066.                     
  1067.                         // clip right
  1068.                     extra = 0;
  1069.                     if ( spanend > dstClipRect->right )
  1070.                     {
  1071.                         extra = spanend - dstClipRect->right;
  1072.                     
  1073.                         count -= extra;
  1074.                     }
  1075.                     
  1076.                     BlitPixieMemSet( dstPixel, *((unsigned long *) srcTokens), count );
  1077.                     
  1078.                     x += extra;
  1079.                     dstPixel += extra;
  1080.                     
  1081.                 }
  1082.                 
  1083.                 x += count;
  1084.                 dstPixel += count;
  1085.                 
  1086.                 srcTokens += sizeof(long);
  1087.                 break;
  1088.             case kLineStartToken:
  1089.                 if ( y < dstClipRect->top )
  1090.                 {
  1091.                         // clip top (skip entire row)
  1092.                     srcTokens += count;
  1093.                 }
  1094.                 else if ( y >= dstClipRect->bottom )
  1095.                 {
  1096.                         // clip bottom (end draw)
  1097.                     op = kEndShapeToken;
  1098.                     break;
  1099.                 }
  1100.                 
  1101.                 x = 0;
  1102.                 y++;
  1103.                 dstPixel = dstRow;
  1104.                 dstRow += dstOffset;
  1105.                 break;
  1106.             case kEndShapeToken:
  1107.                 break;
  1108.             default:
  1109.                 BLITPIXIE_DEBUGGER("BlitPixieRLE : compiled data contains unknown token!");
  1110.                 return;
  1111.             
  1112.         }
  1113.     } while ( op != kEndShapeToken );
  1114.  
  1115. }
  1116.  
  1117. #endif
  1118.  
  1119.  
  1120. #pragma mark -
  1121.  
  1122. #ifndef GENERATINGASM // do not include for asm file generation
  1123.  
  1124. ///--------------------------------------------------------------------------------------
  1125. //        BlitPixieRLEColor - draws the RLE mask in a specific color
  1126. ///--------------------------------------------------------------------------------------
  1127.  
  1128. void BlitPixieRLEColor(
  1129.     unsigned char *srcTokens,    
  1130.     unsigned long srcColor,
  1131.     unsigned char *dstPixel,
  1132.     unsigned long dstRowBytes)
  1133. {
  1134.     unsigned long    token,op,count;
  1135.     unsigned char     *dstRow;
  1136.     
  1137.     dstRow = dstPixel;
  1138.     
  1139.     do
  1140.     {
  1141.         token = *((TokenDataType *) srcTokens);
  1142.         srcTokens += sizeof(TokenDataType);
  1143.         
  1144.         op = token >> kTokenShift;
  1145.         count = token & kCountMask;
  1146.     
  1147.         switch ( op )
  1148.         {
  1149.             case kDrawPixelsToken:
  1150.                 BlitPixieMemSet( dstPixel, srcColor, count );
  1151.                 dstPixel += count;
  1152.                 srcTokens += count;
  1153.                 srcTokens += ALIGN_PTR(srcTokens);
  1154.                 break;
  1155.             case kSkipPixelsToken:
  1156.                 dstPixel += count;
  1157.                 break;
  1158.             case kSingleColorToken:
  1159.                 BlitPixieMemSet( dstPixel, srcColor, count );
  1160.                 dstPixel += count;
  1161.                 srcTokens += sizeof(long);
  1162.                 break;
  1163.             case kLineStartToken:
  1164.                 dstPixel = dstRow;
  1165.                 dstRow += dstRowBytes;
  1166.                 break;
  1167.             case kEndShapeToken:
  1168.                 break;
  1169.             default:
  1170.                 BLITPIXIE_DEBUGGER("BlitPixieRLE : compiled data contains unknown token!");
  1171.                 return;
  1172.         }
  1173.     
  1174.     } while ( op != kEndShapeToken );
  1175.     
  1176. }
  1177.  
  1178. ///--------------------------------------------------------------------------------------
  1179. //        BlitPixieRLEColorClipped
  1180. ///--------------------------------------------------------------------------------------
  1181.  
  1182. void BlitPixieRLEColorClipped(
  1183.     unsigned char *srcTokens,
  1184.     unsigned long srcColor,
  1185.     unsigned char *dstPixel,
  1186.     unsigned long dstOffset,
  1187.     Rect *dstClipRect )
  1188. {
  1189.     unsigned short        token,op;
  1190.     long                count,extra,spanend;
  1191.     unsigned char        *dstRow;
  1192.     int                    x,y;
  1193.  
  1194.     y = 0;
  1195.     dstRow = dstPixel;
  1196.     
  1197.     do
  1198.     {
  1199.         token = *((TokenDataType *) srcTokens);
  1200.         srcTokens += sizeof(TokenDataType);
  1201.  
  1202.         op = token >> kTokenShift;
  1203.         count = token & kCountMask;
  1204.     
  1205.         switch ( op )
  1206.         {
  1207.             case kDrawPixelsToken:
  1208.                 
  1209.                 spanend = x + count - 1;
  1210.                 
  1211.                 if ( x < dstClipRect->right && spanend > dstClipRect->left )
  1212.                 {
  1213.                         // clip left
  1214.                     if ( x < dstClipRect->left )
  1215.                     {
  1216.                         extra = dstClipRect->left - x;
  1217.                     
  1218.                         count -= extra;
  1219.                     
  1220.                         x += extra;
  1221.                         dstPixel += extra;
  1222.                         srcTokens += extra;
  1223.                     }
  1224.                     
  1225.                         // clip right
  1226.                     extra = 0;
  1227.                     if ( spanend > dstClipRect->right )
  1228.                     {
  1229.                         extra = spanend - dstClipRect->right;
  1230.                     
  1231.                         count -= extra;
  1232.                     }
  1233.                     
  1234.                     BlitPixieMemSet( dstPixel, srcColor, count );
  1235.                     
  1236.                     x += extra;
  1237.                     dstPixel += extra;
  1238.                     srcTokens += extra;
  1239.                     
  1240.                 }
  1241.                 
  1242.                 x += count;
  1243.                 dstPixel += count;
  1244.                 srcTokens += count;
  1245.                 srcTokens += ALIGN_PTR(srcTokens);
  1246.                 
  1247.                 break;
  1248.             
  1249.             case kSkipPixelsToken:
  1250.                 x += count;
  1251.                 dstPixel += count;
  1252.                 break;
  1253.             
  1254.             case kSingleColorToken:
  1255.                 
  1256.                 spanend = x + count -1;
  1257.                 
  1258.                 if ( x < dstClipRect->right && spanend > dstClipRect->left )
  1259.                 {
  1260.                         // clip left
  1261.                     if ( x < dstClipRect->left )
  1262.                     {
  1263.                         extra = dstClipRect->left - x;
  1264.                     
  1265.                         count -= extra;
  1266.                     
  1267.                         x += extra;
  1268.                         dstPixel += extra;
  1269.                     }
  1270.                     
  1271.                         // clip right
  1272.                     extra = 0;
  1273.                     if ( spanend > dstClipRect->right )
  1274.                     {
  1275.                         extra = spanend - dstClipRect->right;
  1276.                     
  1277.                         count -= extra;
  1278.                     }
  1279.                     
  1280.                     BlitPixieMemSet( dstPixel, srcColor, count );
  1281.                     
  1282.                     x += extra;
  1283.                     dstPixel += extra;
  1284.                     
  1285.                 }
  1286.                 
  1287.                 x += count;
  1288.                 dstPixel += count;
  1289.                 
  1290.                 srcTokens += sizeof(long);
  1291.                 break;
  1292.             case kLineStartToken:
  1293.                 if ( y < dstClipRect->top )
  1294.                 {
  1295.                         // clip top (skip entire row)
  1296.                     srcTokens += count;
  1297.                 }
  1298.                 else if ( y >= dstClipRect->bottom )
  1299.                 {
  1300.                         // clip bottom (end draw)
  1301.                     op = kEndShapeToken;
  1302.                     break;
  1303.                 }
  1304.                 
  1305.                 x = 0;
  1306.                 y++;
  1307.                 dstPixel = dstRow;
  1308.                 dstRow += dstOffset;
  1309.                 break;
  1310.             case kEndShapeToken:
  1311.                 break;
  1312.             default:
  1313.                 BLITPIXIE_DEBUGGER("BlitPixieRLE : compiled data contains unknown token!");
  1314.                 return;
  1315.             
  1316.         }
  1317.     } while ( op != kEndShapeToken );
  1318.  
  1319. }
  1320.  
  1321. #endif GENERATINGASM
  1322.